package it.polimi.wcalendar.gui.security;

import it.polimi.wcalendar.business.security.boundary.DistrictManager;
import it.polimi.wcalendar.business.security.boundary.UserManager;
import it.polimi.wcalendar.business.security.boundary.CalendarDataManager;
import it.polimi.wcalendar.business.security.entity.District;
import it.polimi.wcalendar.business.security.entity.Event;
import it.polimi.wcalendar.business.security.entity.Notification;
import it.polimi.wcalendar.business.security.entity.PeopleInvited;
import it.polimi.wcalendar.business.security.entity.User;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import org.primefaces.event.SelectEvent;

/**
 * Gestisce la pagina di creazione degli eventi editevent.xhtml.
 *
 * @author unil
 */
@Named
@SessionScoped
public class EventsBean implements Serializable {

    @EJB
    private CalendarDataManager cm;
    @EJB
    private UserManager um;
    //@EJB
    //private DistrictManager dm;

    private Integer eventId;
    private User user;

    private FacesContext context = FacesContext.getCurrentInstance();

    private Event event;

    private boolean privacy, inOut;
    private String description;
    private Date startDate;
    private Date endDate;
    private String place;
    private Collection<Notification> notificationCollection;
    private Collection<PeopleInvited> peopleInvitedCollection;

    private ArrayList<String> selectedUsers;
    private ArrayList<String> usersNickname;

    public EventsBean() {
    }

    @PostConstruct
    public void init() {
        //TODO
        user = um.getLoggedUser();
        usersNickname = um.getAllUsernames(user.getNickname());
        if (eventId != null) {
            event = cm.loadEvent(eventId);
            if (event.getCreator() != user) {
                try {
                    context.getExternalContext().redirect("/user/home.xhtml");
                } catch (IOException ex) {
                    Logger.getLogger(EventsBean.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            privacy = event.getPrivacy();
            inOut = event.getInOut();
            description = event.getDescription();
            startDate = event.getStartDate();
            endDate = event.getEndDate();
            place = event.getPlace().toString();
            notificationCollection = event.getNotificationCollection();
            peopleInvitedCollection = event.getPeopleInvitedCollection();
            selectedUsers = new ArrayList<>();
            for (Object elem : peopleInvitedCollection) {
                PeopleInvited invited = (PeopleInvited) elem;
                selectedUsers.add(invited.getUser().getNickname());
            }
        }
    }

    /**
     * Metodo bottone "save"
     */
    public String submit() {
        // TODO
        if (eventIsntFine()) {
            context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error! Event inconsistent.", "Event inconsistent."));
            return null;
        } else {
            District district = new District(place);
            /*if (dm.getByName().contains(placeName.toLowerCase())) {
             district = dm.loadDistrict(placeName.toLowerCase());*/
            if (eventId != null) {
                if (selectedUsers != null && !selectedUsers.isEmpty()) {
                    event.setPeopleInvitedCollection(cm.createPeopleInvited(selectedUsers, event));
                    event.setNotificationCollection(cm.createNotificationCol(selectedUsers, event));
                }
                try {
                    cm.updateEvent(eventId, privacy, inOut, description, startDate, endDate, district, notificationCollection, peopleInvitedCollection);
                } catch (EJBException e) {
                    e.printStackTrace();
                }
            } else {
                event = new Event(privacy, description, inOut, endDate, startDate);
                event.setCreator(user);
                //event.setPlace(district);
                if (selectedUsers != null && !selectedUsers.isEmpty()) {
                    event.setPeopleInvitedCollection(cm.createPeopleInvited(selectedUsers, event));
                    event.setNotificationCollection(cm.createNotificationCol(selectedUsers, event));
                }
                try {
                    cm.saveEvent(event);
                } catch (EJBException e) {
                    e.printStackTrace();
                }
            }
            return "/user/home";
        }
    }

    public String delete() {
        if (event != null) {
            cm.deleteEvent(event.getIde());
        }
        return "/user/home";
    }

    private boolean eventIsntFine() {
        if (startDate.after(endDate)) {
            return true;
        }
        if (!cm.getExistingOverlapEvents(user, startDate, endDate).isEmpty()) {
            return true;
        }
        return false;
    }

    public List<String> getSelectedUsers() {
        return selectedUsers;
    }

    public void setSelectedUsers(ArrayList<String> selectedUsers) {
        this.selectedUsers = selectedUsers;
    }

    public ArrayList<String> getUsers() {
        return usersNickname;
    }

    public boolean isPrivacy() {
        return privacy;
    }

    public void setPrivacy(boolean privacy) {
        this.privacy = privacy;
    }

    public boolean isInOut() {
        return inOut;
    }

    public void setInOut(boolean inOut) {
        this.inOut = inOut;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Date getStartDate() {
        return startDate;
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public String getPlace() {
        return place;
    }

    public void setPlace(String place) {
        this.place = place;
    }

}
